package com.asmtest.visitor;

import com.alibaba.fastjson.JSON;
import com.util.ClassInfo;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.objectweb.asm.ClassReader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @author yutianhong
 * @version 1.0
 * @since 2023/12/18 11:40
 */
public class MavenScanner {

    private static final String MAVEN_REPOSITORY = "http://repo.alibaba-inc.com/nexus/content/groups/alirepositiry/";

    public static void main(String[] args) {
        scanMaven("com.alibaba.aecp2", "aecp2-common-oplog", "1.0.0-SNAPSHOT", null);
    }

    static void scanMaven(String groupId, String artifactId, String version, String classifier) {
        String destDir;
        try {
            destDir = Files.createTempDirectory("JarScanner-" + Thread.currentThread().getId() + "-").toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("destDir: " + destDir);
        File file;
        try {
            file = MavenArtifactDownloader.downloadJar(groupId, artifactId, version, classifier, destDir, MAVEN_REPOSITORY);
            scanJarFile(file);
        } catch (ArtifactResolutionException e) {
            throw new RuntimeException(e);
        } finally {
            File fileToDelete = new File(destDir);
            deleteDirectory(fileToDelete);
        }
    }

    private static void scanJarFile(File file) {
        try (JarFile jarFile = new JarFile(file)) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                System.out.println("jarEntry.getName() = " + jarEntry.getName());
                if (!jarEntry.isDirectory() && jarEntry.getName().endsWith(".class")) {
                    System.out.println("read class jarEntry:");
                    try (InputStream inputStream = jarFile.getInputStream(jarEntry)) {
                        ClassReader classReader = new ClassReader(inputStream);
                        Consumer<ClassInfo> consumer = classInfo -> System.out.println("classInfo = " + JSON.toJSONString(classInfo, true));
                        classReader.accept(new AsmScanner.MyDetectingClassVisitor(consumer), 0);
                        System.out.println("------------------------------------------------------------");
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    static void deleteDirectory(File directory) {
        if (directory == null || !directory.exists()) {
            return;
        }
        assert directory.isDirectory();

        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        directory.delete();
    }
}
